package cn.demoncat.util.lang;

import cn.demoncat.util.exception.ReflexRuntimeException;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.PropertyUtils;

import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;

/**
 * 描述：实体类处理工具
 *
 * @author 延晓磊
 *
 * @since 2017年6月13日
 */
public final class BeanUtil {

	private static final String CLASS = "class";
	
	/**
	 * 设置对象的属性
	 *
	 * @param obj	对象
	 * @param field	属性名
	 * @param value	属性值
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2017年6月13日
	 */
	public static void setField(Object obj, String field, Object value) {
		try {
			BeanUtils.setProperty(obj, field, value);
		} catch (IllegalAccessException | InvocationTargetException e) {
			throw new ReflexRuntimeException(e.getMessage(), e);
		}
	}
	
	/**
	 * 获取对象的属性
	 *
	 * @param obj	对象
	 * @param field	属性名
	 * @return	属性值（toString）
	 * 
	 * @author 延晓磊
	 *
	 * @since 2017年6月13日
	 */
	public static String getField(Object obj, String field){
		try {
			return BeanUtils.getProperty(obj, field);
		} catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
			throw new ReflexRuntimeException(e.getMessage(), e);
		}
	}
	
	/**
	 * Map转换为Bean
	 *
	 * @param fields	属性-值 
	 * @param beanClass	对象Class
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2017年6月13日
	 */
	public static Object toObj(Map<String,Object> fields, Class<?> beanClass){
		try {
			Object obj = beanClass.newInstance();
			BeanUtils.populate(obj, fields);
			return obj;
		} catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
			throw new ReflexRuntimeException(e.getMessage(), e);
		} 
	}
	
	/**
	 * 将Bean转为Map
	 *
	 * @param obj
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2017年6月13日
	 */
	public static Map<String,Object> toMap(Object obj){
		 try {
			Map<String, Object> map = PropertyUtils.describe(obj);
			//去除class键
			map.remove(CLASS);
			return map;
		} catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
			throw new ReflexRuntimeException(e.getMessage(), e);
		}
	}
	
	/**
	 * 将Bean转为Map<String,String>
	 *
	 * @param obj
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2017年6月13日
	 */
	public static Map<String,String> toStrMap(Object obj){
		Map<String, String> map = new HashMap<>();
		for (Entry<String, Object> entry : toMap(obj).entrySet()) {
			map.put(entry.getKey(), StringUtil.toString(entry.getValue()));
		}
		return map;
	}
	
	/**
	 * 克隆
	 *
	 * @param obj
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2017年6月27日
	 */
	public static Object clone(Object obj){
		try {
			return BeanUtils.cloneBean(obj);
		} catch (IllegalAccessException | InstantiationException | InvocationTargetException
				| NoSuchMethodException e) {
			throw new ReflexRuntimeException(e.getMessage(), e);
		}
	}

	/**
	 * 拷贝：将原对象的所有属性拷贝到目标对象
	 * 
	 * @param old	原对象
	 * @param desc	目标对象
	 * 
	 * @author 延晓磊
	 *
	 * @since 2019年11月25日
	 */
	public static void copy(Object old, Object desc) {
		try {
			BeanUtils.copyProperties(desc, old);
		} catch (IllegalAccessException | InvocationTargetException e) {
			throw new ReflexRuntimeException(e.getMessage(), e);
		}
	}
}
